﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Audio;

namespace GlobalGameJam
{
    public class GameplayScreen : AGameScreen
    {
        ContentManager content;
        SpriteFont gameFont;
        Song _song;
        SoundEffect _hamsterSound;
        SoundEffect _hamsterSound1;
        SoundEffect _hamsterSound2;
        SoundEffect _hamsterSound3;
        SoundEffect _hamsterSound4;
        SoundEffect _hamsterSound5;
        SoundEffect _bubbleSound;
        SoundEffect _hamsterCrunch;
        SoundEffectInstance _soundInstance;
        Plateform blockingPlat;
        int nbNerves;

        List<SoundEffect> _soundEffectList = new List<SoundEffect>();

        float pauseAlpha;
        float timer;


        SpriteBatch spriteBatch;
        Gravite g;
        public Player player;
        Snake s;
        public List<Plateform> plateforms;
        public CollisionManager collisionManager;

        public GameplayScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);
            name = "GameplayScreen";
        }

        public override void Initialize()
        {
            // TODO: Add your initialization logic here
            this.player = new Player(this);
            collisionManager = new CollisionManager();
            this.g = new Gravite(player, plateforms, this);
            this.s = new Snake(100, 100);
            base.Initialize();
        }

        public override void LoadContent()
        {
            nbNerves = 0;
            this.Initialize();
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");
            _song = content.Load<Song>("musique_ambiance");
            _hamsterSound = content.Load<SoundEffect>("hamster");
            _hamsterSound1 = content.Load<SoundEffect>("hamster1");
            _hamsterSound2 = content.Load<SoundEffect>("hamster2");
            _hamsterSound3 = content.Load<SoundEffect>("hamster3");
            _hamsterSound4 = content.Load<SoundEffect>("hamster4");
            _hamsterSound5 = content.Load<SoundEffect>("hamster5");
            _bubbleSound = content.Load<SoundEffect>("bubblesound");
            _hamsterCrunch = content.Load<SoundEffect>("crunching-1");
            MediaPlayer.IsRepeating = true;

            spriteBatch = ScreenManager.SpriteBatch;
            Texture2D textPlayer = this.content.Load<Texture2D>("soloSprite");
            Texture2D textDown = this.content.Load<Texture2D>("estomac1/down");
            this.player.Initialize(textPlayer, Vector2.Zero, new Vector2(1200, 800));

            Plateform toAdd;
            Texture2D textToAff;
            Bubble toAddBubble;

            textToAff = this.content.Load<Texture2D>("bubbles/bull1");
            toAddBubble = new Bubble(this);
            toAddBubble.Initialize(textToAff, new Vector2(1200 + 150 + 500, -900 * 2 + 2000 - 200), 500, new Vector2(0, -1));
            toAddBubble.setPopping(this.content.Load<Texture2D>("bubbles/bull2"));
            toAddBubble.setPop(this.content.Load<Texture2D>("bubbles/bull3"));
            collisionManager.plateforms.Add(toAddBubble);

            textToAff = this.content.Load<Texture2D>("bubbles/bull1");
            toAddBubble = new Bubble(this);
            toAddBubble.Initialize(textToAff, new Vector2(1200 + 150 + 500, -900 * 2 + 2000 - 200), 700, new Vector2(0, -1));
            toAddBubble.setPopping(this.content.Load<Texture2D>("bubbles/bull2"));
            toAddBubble.setPop(this.content.Load<Texture2D>("bubbles/bull3"));
            collisionManager.plateforms.Add(toAddBubble);

            // NERFS
            Button toAddButton;
            textToAff = this.content.Load<Texture2D>("nerf_0");
            toAddButton = new Button(this);
            toAddButton.Initialize(textToAff, new Vector2(600 - 290, 700 - 100), 0, new Vector2(0, 0));
            toAddButton.setType("nerf");
            toAddButton.addText(this.content.Load<Texture2D>("nerf_1"));
            collisionManager.plateforms.Add(toAddButton);
            nbNerves += 1;
            
            textToAff = this.content.Load<Texture2D>("nerfup_0");
            toAddButton = new Button(this);
            toAddButton.Initialize(textToAff, new Vector2(1200 * 2 + 350, 2700), 0, new Vector2(0, 0));
            toAddButton.setType("nerf");
            toAddButton.addText(this.content.Load<Texture2D>("nerfup_1"));
            collisionManager.plateforms.Add(toAddButton);
            nbNerves += 1;

            // BLOCKER
            textToAff = this.content.Load<Texture2D>("estomac1/plat1");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 + 150 + 100, -900 * 2 + 2000 - 200), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            blockingPlat = toAdd;


            textToAff = this.content.Load<Texture2D>("level/3");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(0 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/a4");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(0 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/11");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 + 150, -900 * 3 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/4");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/b4");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/5");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/c1");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/6");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/d4");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/7");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, -900 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/d3");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, -900 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/8");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, -900 * 2 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/d2");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, -900 * 2 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/9");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, -900 * 3 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/d1");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 3 + 150, -900 * 3 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/10");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150, -900 * 3 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/c1");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150, -900 * 3 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);


            textToAff = this.content.Load<Texture2D>("estomac1/plat4");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150 + 300, -900 * 3 + 2000 + 250), 400, new Vector2(1, 0));
            collisionManager.plateforms.Add(toAdd);
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150 + 700, -900 * 3 + 2000 + 700), 400, new Vector2(0, -1));
            collisionManager.plateforms.Add(toAdd);




            textToAff = this.content.Load<Texture2D>("level/12");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 0 + 150, -900 * 3 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/1");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 0 + 150, -900 * 2 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/a2");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 0 + 150, -900 * 2 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);

            textToAff = this.content.Load<Texture2D>("level/2");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 0 + 150, -900 * 1 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/a3");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 0 + 150, -900 * 1 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms2.Add(toAdd);


            textToAff = this.content.Load<Texture2D>("level/b2");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 + 150, -900 * 2 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/b3");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 + 150, -900 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/c3");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150, -900 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);
            textToAff = this.content.Load<Texture2D>("level/c2");
            toAdd = new Plateform(this);
            toAdd.Initialize(textToAff, new Vector2(1200 * 2 + 150, -900 * 2 + 2000), new Vector2(0, 0), new Vector2(0, 0), new Vector2(0, 0));
            collisionManager.plateforms.Add(toAdd);

            this.player.LoadContent(this.content, "inputManager");
            this.s.Initialize(new Vector2(1200, 800));
        }

        public override void UnloadContent()
        {
            content.Unload();
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);
            if (otherScreenHasFocus)
                MediaPlayer.Stop();
            else
            {
                if (OptionsMenuScreen.CurrentMusic == 0 && MediaPlayer.State == MediaState.Stopped)
                    MediaPlayer.Play(_song);
                else if (OptionsMenuScreen.CurrentMusic == 1 && MediaPlayer.State == MediaState.Playing)
                    MediaPlayer.Stop();
                if (OptionsMenuScreen.CurrentSound == 0)
                {
                    timer += gameTime.ElapsedGameTime.Milliseconds;
                    if (timer >= 5000)
                    {
                        Random rnd = new Random();
                        int nb = rnd.Next(1, 5);
                        if (nb == 1)
                            playSound(_hamsterSound1);
                        if (nb == 2)
                            playSound(_hamsterSound2);
                        if (nb == 3)
                            playSound(_hamsterSound3);
                        if (nb == 4)
                            playSound(_hamsterSound4);
                        if (nb == 5)
                            playSound(_hamsterSound5);
                        timer = 0;
                    }
                }
            }
            if (IsActive)
            {
                /*if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();*/
                //KeyboardState state = Keyboard.GetState();

                foreach (Plateform p in collisionManager.plateforms)
                    p.Update(gameTime);
                // TODO: Add your update logic here
                this.player.Update(gameTime);
                this.Collisions(gameTime);
                //base.Update(gameTime);
            }
            else
                MediaPlayer.Stop();
            this.s.Update();
        }

        public void Collisions(GameTime gametime)
        {
            this.g.checkGravite(gametime);
        }

        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");

            int playerIndex = (int)ControllingPlayer.Value;
            KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];

            // a modif avec notre propre systeme d'input
            if (input.IsPauseGame(ControllingPlayer))
            {
                MediaPlayer.Stop();
                ScreenManager.AddScreen(new PauseMenuScreen(), ControllingPlayer);
            }
            else
            {
                //if (keyboardState.IsKeyDown(Keys.N))
                //{
                //    if (this.g.direction == 0)
                //        this.g.setDir(1);
                //    else
                //        this.g.setDir(0);
                //}

                //if (keyboardState.IsKeyDown(Keys.D))
                //{
                //    player.position.X = 100;
                //    player.position.Y = 200;
                //    player.UpdateHitbox();
                //}
                if (keyboardState.IsKeyDown(Keys.Tab))
                {
                    SnakeScreen.Move = true;
                    ScreenManager.AddScreen(SnakeScreen.getInstance(), ControllingPlayer);
                }
                
            }
        }

        public override void Draw(GameTime gameTime)
        {
            if (TransitionPosition > 0 || pauseAlpha > 0)
            {
                float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

                ScreenManager.FadeBackBufferToBlack(alpha);
            }
            else
            {
                //GraphicsDevice.Clear(Color.Pink);

                // TODO: Add your drawing code here

                this.player.Draw(gameTime, spriteBatch);
                foreach (Plateform p in collisionManager.plateforms)
                    p.Draw(gameTime, spriteBatch);
                foreach (Plateform p in collisionManager.plateforms2)
                    p.Draw(gameTime, spriteBatch);
 this.s.Draw();
                base.Draw(gameTime);
            }
        }

        public void playSound(SoundEffect sound)
        {
            SoundEffectInstance soundInstance;
            
            soundInstance = sound.CreateInstance();
            soundInstance.Play();
        }
        public void notifyEvent(string type)
        {
            if (type == "bubblePop")
                playSound(_bubbleSound);
            else if (type == "nerf")
            {
                nbNerves--;
                playSound(_hamsterCrunch);
                if (nbNerves <= 0)
                    blockingPlat.position.X -= 100;
            }
        }
    }
}
